#!/usr/bin/env python

# Imports:
# -------
import wx, os
from labeler_panel import *
from annotation_panel import *

# Constants & configuration:
M_FILE_QUIT_ID = 1
M_FILE_OPEN_ID = 2
M_HELP_ABOUT_ID = 3

# -----------------------
class MainFrame(wx.Frame):
# -----------------------
	# Members:
	# + bagLabeler -- The actual labeler 
	# + menuBar -- The application's menu bar 
	# + sizer -- The frame's sizer
	# + labelerPanel -- The labeler panel
	# + annotationPanel -- The panel for annotating labels

	# ----------------------------------------
	def __init__(self, bagLabeler, name, size):
	# ----------- ----------------------------
		# Initialze the frame
		wx.Frame.__init__(self, None, wx.ID_ANY, name, size=size)
		
		# Save the labeler
		self.bagLabeler = bagLabeler

		# Setup the menu bar
		self.menuBar = wx.MenuBar()
		self.SetMenuBar(self.menuBar)

		# File menu:
		# ---------
		mFile = wx.Menu()
		self.menuBar.Append(mFile, '&File')

		# Open
		mFileOpen = wx.MenuItem(mFile, M_FILE_OPEN_ID, '&Open\tCtrl+O')
		self.Bind(wx.EVT_MENU, self.onOpen, id=M_FILE_OPEN_ID)
		mFile.AppendItem(mFileOpen)

		# Quit
		mFileQuit = wx.MenuItem(mFile, M_FILE_QUIT_ID, '&Quit\tCtrl+Q')
		self.Bind(wx.EVT_MENU, self.onQuit, id=M_FILE_QUIT_ID)
		mFile.AppendItem(mFileQuit)

		# Help menu:
		# ---------
		mHelp = wx.Menu()
		mHelpAbout = wx.MenuItem(mHelp, M_HELP_ABOUT_ID, '&About')
		self.Bind(wx.EVT_MENU, self.onAbout, id=M_HELP_ABOUT_ID)
		mHelp.AppendItem(mHelpAbout)
		self.menuBar.Append(mHelp, '&Help')

		# Create the sizer
		self.sizer = wx.BoxSizer(wx.HORIZONTAL)
		self.SetSizer(self.sizer)

		# Create and add the annotation panel
		# -----------------------------------
		self.annoationPanel = AnnotationPanel(self)
		self.sizer.Add(self.annoationPanel, 1, wx.EXPAND)

		# Create and add the labeler panel
		# --------------------------------
		self.labelerPanel = LabelerPanel(self)	
		self.sizer.Add(self.labelerPanel, 3, wx.EXPAND)
		self.Bind(wx.EVT_BUTTON, self.onLeft, self.labelerPanel.leftButton)
		self.Bind(wx.EVT_BUTTON, self.onRight, self.labelerPanel.rightButton)
		self.Bind(wx.EVT_CHAR_HOOK, self.leftRightDispatch)
		self.labelerPanel.SetFocus()

		# Get mouse events for the image
		#self.labelerPanel.image.Bind(wx.EVT_LEFT_DOWN, self.onLeftMouseDown)
		#self.labelerPanel.image.Bind(wx.EVT_LEFT_UP, self.onLeftMouseUp)
		#self.labelerPanel.image.Bind(wx.EVT_MOTION, self.onMouseMove)

		# Wire up the close event
		self.Bind(wx.EVT_CLOSE, self.onClose)

		# Put everything together
		self.Layout()

	# ---------------------
	def onOpen(self, event):
	# ---------------------
		# Open a dialog box for choosing (opening a file)
		openDlg = wx.FileDialog(self, "Choose a ROS Bag", "~", "", "*.bag", wx.OPEN)
		if openDlg.ShowModal() == wx.ID_OK:
			fileName = openDlg.GetFilename()
			dirName = openDlg.GetDirectory()
			fullPath = os.path.join(dirName, fileName)
			openDlg.Destroy()

			self.bagLabeler.loadBag(fullPath, callback=self.onBagLoad)
		else:
			openDlg.Destroy()

	# ------------------------------------------------
	def onBagLoad(self, imageTopics, annotationTopics):
	# ------------------------------------------------
		# Display the loaded (and relevant) topics
		self.labelerPanel.displayImageTopics(imageTopics)
		self.labelerPanel.displayAnnotationTopics(annotationTopics)

		# Enable the left/right buttons
		self.labelerPanel.rightButton.Enable()
		self.labelerPanel.leftButton.Enable()

		# Get the first image and display it
		topic, img, t = self.bagLabeler.curr()
		self.labelerPanel.displayImage(img)

		# Highlight the loaded topic
		self.labelerPanel.selectImageTopic(topic)

		# Show the progress
		i,tot = self.bagLabeler.getIndex()
		self.labelerPanel.displayProgress(i, tot)
		

	# ---------------------
	def onQuit(self, event):
	# ---------------------
		""" Called when the 'Quit' button is pressed in the menu """

		self.Close()

	# ----------------------
	def onAbout(self, event):
	# ----------------------
		""" Launches an 'about' dialog """

		info = wx.AboutDialogInfo()
		info.SetIcon(wx.Icon('resources/bag.png', wx.BITMAP_TYPE_PNG))
		info.SetName('Bag Labeler')
		info.SetVersion('0.1')
		info.SetDescription('A simple tool for labeling ROS bags.\n Written by Walker Burgin, Feb. 2011')
		info.SetWebSite('http://www.ros.org')
		info.AddDeveloper('Walker Burgin - <walkerburgin@gmail.com>')
		wx.AboutBox(info)
		
	# ----------------------
	def onClose(self, event):
	# ----------------------
		""" Called when the application is closed """ 

		# Shutdown the bag labeler
		self.bagLabeler.shutdown()

		# Destroy the GUI window
		self.Destroy()

	# ---------------------
	def onLeft(self, event):
	# ---------------------
		if self.bagLabeler.isBagLoaded():
			# Get & display the next image
			topic, img, t = self.bagLabeler.prev()
			self.labelerPanel.displayImage(img)

			# Display the progress
			i, tot = self.bagLabeler.getIndex()
			self.labelerPanel.displayProgress(i,tot)


	# ----------------------
	def onRight(self, event):
	# ----------------------
		if self.bagLabeler.isBagLoaded():
			# Get & display the next image
			topic, img, t = self.bagLabeler.next()
			self.labelerPanel.displayImage(img)

			# Display the progress
			i, tot = self.bagLabeler.getIndex()
			self.labelerPanel.displayProgress(i,tot)

	# --------------------------------
	def leftRightDispatch(self, event):
	# --------------------------------
		kc = event.GetKeyCode()
		if kc == wx.WXK_RIGHT or kc == ord('d'):
			self.onRight(event)
		elif kc == wx.WXK_LEFT or kc == ord('a'):
			self.onLeft(event) 
		else:
			event.Skip()

	# ------------------------------
	def onLeftMouseDown(self, event):
	# ------------------------------
		self.mouseDownPose = event.GetPositionTuple()

		# Make sure anybody else who needs the event can get it
		event.Skip()

	# ----------------------------
	def onLeftMouseUp(self, event):
	# ----------------------------
		mouseUpPos = event.GetPositionTuple()
		x,y = self.mouseDownPose

		print x,y
		print mouseUpPos

		# Make sure anybody else who needs the event can get it
		event.Skip()

	# --------------------------
	def onMouseMove(self, event):
	# --------------------------
		# Draw the rectangle 
		pass
